'''
代码逻辑详解
数据读取与预处理：

使用 pandas 从Excel文件读取数据。
只选取前100行数据来简化处理过程和减少计算量。
选择关键的化学和物理特性列，使用这些列来计算相似性和添加图的边。
特征标准化：

使用 StandardScaler 对选定的特征进行标准化处理。这一步骤是为了确保不同特征之间的比较是公平的，尤其是在计算相似性时，不同量级的数据可能会影响结果。
相似性矩阵计算：

使用 cosine_similarity 计算标准化特征之间的相似度。这个相似度将用于后续确定节点间是否应该建立边。
图的构建：

创建一个 MultiGraph，这允许同一对节点之间可以有多条边，对应不同的连接类型。
为每个节点添加标签和质量信息作为节点属性。
循环遍历每一对节点，根据质量差异、相对丰度和DBE差异判断是否添加边。每种类型的边使用不同的颜色标识。
绘图和可视化：

使用 matplotlib 和 networkx 的 draw 函数来绘制图。
使用 Kamada-Kawai 布局算法，这是一个常用的图布局算法，特别适合于复杂网络的可视化，因为它尝试使边的长度均匀并减少边的交叉。
使用边的颜色来区分不同类型的连接。


可能的优化
动态调整阈值：

可以设定一个界面或工具来动态调整边的阈值，以便用户根据具体情况调整图的密度和复杂度。
增强的数据过滤：

在选择数据和特征时，可能需要进一步分析哪些特征最具代表性和影响力，从而优化图的信息价值。
高级图形交互功能：

使用 Plotly 或 Bokeh 这类库替代 matplotlib，可以提供更丰富的交互功能，如点击节点显示详细信息、交互式地修改图形显示设置等。
并行处理：

当处理大规模数据集时，特征的标准化、相似性计算和图的构建可能非常耗时。可以考虑使用并行处理技术来加速这些计算。
'''


import pandas as pd
import networkx as nx
from sklearn.preprocessing import StandardScaler
from sklearn.metrics.pairwise import cosine_similarity

# 读取数据
df = pd.read_excel(r"water_tu/data/20231128HESI-122_001.xlsx", sheet_name="Result")

# 为了示例，我们只使用前100行数据
data = df.head(100)

# 选择和预处理特征
features_columns = ['C', 'H', 'O', 'N', 'S', 'P', 'Cl', 'Error(ppb)', 'Neutral Mass', 'Intensity', 'Relative Abundance', 'Measured Mass', 'DBE', 'NOSC']
features = data[features_columns].fillna(0)

# 标准化特征
scaler = StandardScaler()
scaled_features = scaler.fit_transform(features)

# 计算相似性矩阵
similarity_matrix = cosine_similarity(scaled_features)

# 创建图
G = nx.MultiGraph()  # 使用MultiGraph允许多条边

# 添加节点
for idx, row in data.iterrows():
    G.add_node(idx, label=f"Compound_{idx}", mass=row['Neutral Mass'])

# 添加边的逻辑
mass_tolerance = 0.2  # 质量差异容忍值
intensity_ratio_threshold = 0.01  # 相对丰度比容忍值
dbe_tolerance = 0.01  # DBE差异容忍值

edge_types = {
    'mass_diff': 'blue',
    'intensity_diff': 'green',
    'dbe_diff': 'red'
}

for i in range(similarity_matrix.shape[0]):
    for j in range(i + 1, similarity_matrix.shape[1]):
        # 检查质量差异
        if abs(data.loc[i, 'Measured Mass'] - data.loc[j, 'Measured Mass']) < mass_tolerance:
            G.add_edge(i, j, color=edge_types['mass_diff'])

        # 检查相对丰度差异
        if abs(data.loc[i, 'Relative Abundance'] - data.loc[j, 'Relative Abundance']) < intensity_ratio_threshold:
            G.add_edge(i, j, color=edge_types['intensity_diff'])

        # 检查DBE差异
        if abs(data.loc[i, 'DBE'] - data.loc[j, 'DBE']) < dbe_tolerance:
            G.add_edge(i, j, color=edge_types['dbe_diff'])

# 输出图信息
print(f"Total number of nodes: {G.number_of_nodes()}")
print(f"Total number of edges: {G.number_of_edges()}")

# 可选：绘制图形，视图的可视化可能需要安装matplotlib
import matplotlib.pyplot as plt # 绘制图形
# 使用Kamada-Kawai布局改善视觉效果
pos = nx.kamada_kawai_layout(G)
edges = G.edges(data=True)
colors = [edata['color'] for _, _, edata in edges]  # 提取颜色
nx.draw(G, pos, node_size=20, edge_color=colors, with_labels=False, node_color='lightblue')

plt.show()